home *** CD-ROM | disk | FTP | other *** search
- /*
- * Program to obscure the meaning of a MICRO-C source file by
- * removing comments, indenting, and line spacing. All non-reserved
- * words are replaced with meaningless numeric names.
- *
- * Syntax: obscure <input_file> [output_file] [options]
- *
- * Options: k=<filename> - File of names to KEEP (1 per line).
- * d=<filename> - File of names to PRE-DEFINE (1 per line).
- * p=<string> - Prefix pre-pended to generated numeric names.
- *
- * Use 'k=' to prevent certain names from being obscured.
- * Use 'd=' to insure that certain names will have the same obscured
- * name in several modules (For "extern"s etc.).
- * Default 'p=' prefix is '_'.
- *
- * For MAXIMUM obscuring, use the pre-processor (MCP) before processing
- * with this program. This will remove all pre-processor directives, but BE
- * WARNED that this will make the program LESS PORTABLE, since key system
- * header files (Such as <stdio.h>) will not be re-used when moving to a
- * a new system.
- *
- * Copyright 1989-1994 Dave Dunfield
- * All rights reserved.
- *
- * Permission granted for personal (non-commercial) use only.
- *
- * Compile command: cc obscure -fop
- */
- #include <stdio.h>
-
- #define NUMNEW 500 /* maximum number of unique words */
- #define NUMKEEP 100 /* maximum number of kept words */
- #define FREEPOOL 15000 /* size of free storage pool */
- #define MAXWIDTH 70 /* maximum width of output line */
-
- /* table of reserved words to keep without changing */
- char *resword[] = {
- /* MICRO-C keywords */
- "break", "case", "char", "continue", "default", "do", "else",
- "extern", "for", "goto", "if", "int", "register", "return", "static",
- "switch", "unsigned", "while", "include", "define", "endif" ,"ifdef",
- "ifndef", "undef", "forget", "struct", "union", "sizeof",
- /* MICRO-C library functions */
- "abort", "fprintf", "islower", "peekw", "strchr", "abs", "fwrite",
- "isspace", "poke", "strcmp", "atoi", "fputs", "isupper", "pokew",
- "strcpy", "cd", "free", "longjmp", "printf", "strlen", "concat",
- "fscanf", "malloc", "putc", "strncat", "create", "fseek", "max",
- "rename", "strncmp", "delete", "ftell", "memcpy", "rewind", "strncpy",
- "exit", "getc", "memset", "rmdir", "strstr", "fclose", "getenv", "min",
- "scanf", "system", "fread", "getdir", "mkdir", "setjmp", "toupper",
- "fgets", "in", "nargs", "sprintf", "tolower", "find_first", "inw",
- "out", "sscanf", "find_next", "isalpha", "outw", "strbeg", "fopen",
- "isdigit", "peek", "strcat", "alloc_seg", "vdraw_box", "get_es", "tsr",
- "Cclose", "vtstc", "enable", "get_time", "updatexy", "Cgetc", "rand",
- "vclear_box", "exec", "gotoxy", "version", "Copen", "clear_eol",
- "free_seg", "vgets", "Cputc", "clear_eos", "Ctestc", "resize_seg",
- "Csignals", "clscr", "get_attr", "set_attr", "isalnum", "fflush",
- "vopen", "vgetc", "vputc", "vmenu", "copy_seg", "get_cs", "vmessage",
- "cursor_off", "cursor_line", "cursor_block", "get_date", "set_date",
- "set_drive", "vprintf", "get_drive", "set_es", "vputf", "disable",
- "get_ds", "set_time", "vputs", "save_video", "restore_video", "main",
- "open", "close", "read", "write", "lrewind", "lseek", "ltell", "lprintf",
- "lgetc", "lputc", "lgets", "lputs", "setbuf", "cpu", "int86",
- /* Common header file definitions */
- "FILE", "EOF", "NULL", "stdin", "stdout", "stderr", "mc", "h", "comm",
- "console", "ctype", "file", "stdio", "tsr", "window", "video",
- 0 };
-
- unsigned new_count = 0, keep_count = 0, width = 0;
-
- int inpos = -1;
-
- char *new_text[NUMNEW], *keep_text[NUMKEEP], buffer[200],
- free_text[FREEPOOL], *free_ptr, *prefix = "_", pflag = 0;
-
- FILE *fpr = 0, *fpw;
-
- /*
- * Main program
- */
- main(argc, argv)
- int argc;
- char *argv[];
- {
- int chr, chr1, i;
- char *ptr;
- FILE *fp;
-
- free_ptr = free_text;
-
- fpw = stdout;
- for(i=1; i < argc; ++i) {
- ptr = argv[i];
- switch((*ptr++ << 8) | *ptr++) {
- case 'p=' : /* define generation prefix */
- prefix = ptr;
- break;
- case 'd=' : /* define symbols in advance */
- fp = fopen(ptr, "rvq");
- while(fgets(buffer, 100, fp)) {
- new_text[new_count++] = free_ptr;
- ptr = buffer;
- do
- *free_ptr++ = *ptr;
- while(*ptr++); }
- fclose(fp);
- break;
- case 'k=' : /* define names to keep */
- fp = fopen(ptr, "rvq");
- while(fgets(buffer, 100, fp)) {
- keep_text[keep_count++] = free_ptr;
- ptr = buffer;
- do
- *free_ptr++ = *ptr;
- while(*ptr++); }
- fclose(fp);
- break;
- default: /* filename */
- if(!fpr)
- fpr = fopen(argv[i], "rvq");
- else if(fpw == stdout)
- fpw = fopen(argv[i], "wvq");
- else
- abort("Too many operands\n"); } }
-
- /* if no input file specified, report error */
- if(!fpr) {
- fputs("\nUse: obscure <input_file> [output_file d=definefile k=keepfile p=prefix]\n", stderr);
- abort("\nCopyright 1989-1994 Dave Dunfield\nAll rights reserved.\n"); }
-
- keep_text[keep_count] = new_text[new_count] = 0;
-
- while((chr = read_char()) >= 0) {
- top: switch(chr) {
- case '\n' : /* newline */
- if(pflag) {
- putc('\n', fpw);
- pflag = width = 0; }
- case '\t' : /* ignore tab */
- case ' ' : /* ignore space */
- break;
- case '/' : /* starting comment */
- if((chr = read_char()) == '*') {
- do
- if((chr1 = read_char()) < 0)
- abort("End of file in comment\n");
- while((chr = (chr << 8) + chr1) != '*/'); }
- else {
- write_char('/');
- goto top; }
- break;
- case '"' : /* string input */
- case '\'': /* character input */
- buffer[i=0] = chr;
- do {
- buffer[++i] = chr1 = read_char();
- if(chr1 == '\\')
- buffer[++i] = read_char(); }
- while(chr1 != chr);
- buffer[++i] = 0;
- check_width(width+i);
- write_string(buffer);
- break;
- case '#' : /* pre-processor statements */
- if(!inpos) {
- pflag = -1;
- if(width) {
- putc('\n', fpw);
- width = 0; } }
- default: /* all other characters */
- if(isvar(chr)) { /* Variable name */
- check_width(width);
- buffer[i = 0] = chr;
- do
- buffer[++i] = chr = read_char();
- while(isvar(chr) || isdigit(chr));
- buffer[i] = 0;
- if((!lookup(resword)) && !lookup(keep_text)) {
- if(!(chr1 = lookup(new_text))) {
- new_text[new_count++] = free_ptr;
- ptr = buffer;
- do
- *free_ptr++ = *ptr;
- while(*ptr++);
- new_text[chr1 = new_count] = 0; }
- sprintf(buffer, "%s%u", prefix, chr1); }
- write_string(buffer);
- while(isspace(chr)) {
- if(pflag && (chr == '\n'))
- break;
- chr = read_char(); }
- if(isvar(chr) || isdigit(chr))
- write_char(' ');
- goto top; }
- else if(isdigit(chr)) { /* number */
- check_width(width);
- do
- write_char(chr);
- while(isdigit(chr = read_char()));
- if(chr == 'x') {
- do {
- write_char(chr);
- chr = read_char(); }
- while(isxdigit(chr)); }
- goto top; }
- else
- write_char(chr); } }
- fclose(fpw);
- }
-
- /*
- * Lookup the buffered word in a table
- */
- lookup(table)
- char *table[];
- {
- int i;
- char *ptr;
-
- i = 0;
- while(ptr = table[i++])
- if(!strcmp(buffer, ptr))
- return i;
- return 0;
- }
-
- /*
- * Test for valid variable character
- */
- isvar(chr)
- char chr;
- {
- return ((chr >= 'a') && (chr <= 'z')) ||
- ((chr >= 'A') && (chr <= 'Z')) ||
- (chr == '_');
- }
-
- /*
- * Read a character from the input file
- */
- read_char()
- {
- char chr;
-
- inpos = ((chr = getc(fpr)) == '\n') ? -1 : inpos + 1;
- return chr;
- }
-
- /*
- * Write a character to the file
- */
- write_char(chr)
- char chr;
- {
- putc(chr, fpw);
- ++width;
- }
-
- /*
- * Write a string to the file
- */
- write_string(string)
- char *string;
- {
- while(*string) {
- putc(*string++, fpw);
- ++width; }
- }
-
- /*
- * Check for over width in output file
- */
- check_width(value)
- unsigned value;
- {
- if(value >= MAXWIDTH) {
- putc('\n', fpw);
- width = 0; }
- }
-